#include "prekompil.h"
#include "skaner.h"
#include "opcje.h"
#include "ftplib.h"

#define TIMEOUT_POLACZENIA 500
#define TIMEOUT_SKANOWANIA 3600

ZarzadcaSkanowania * ZarzadcaSkanowania::zarzadca_skanowania = 0;
SekcjaKrytyczna ZarzadcaSkanowania::sekcja_zarzadcy;

void ZalogujBlad(ostream & plik, char * tekst)
   {
   //char bufor[32000];

   plik << tekst << endl;
   //FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, blad, 0, bufor, 32000, NULL);
//   plik << "Blad nr " <<  << ", tresc : " << bufor;
//   if (blad == ERROR_INTERNET_EXTENDED_ERROR)
//      {
//      DWORD numer;
//      DWORD rozmiar = 32000;
//      InternetGetLastResponseInfo(&numer, bufor, &rozmiar);
//      plik << ", blad WinInet nr " << numer << ", tresc : ";
//      plik.write(bufor, rozmiar);
//      }
   throw WyjatekSkanera();
   plik << endl;
 }

DaneUslugi dane_uslug[] =
   {
   {UslugaFTP, "ftp", OtworzFTP},       //param1-enum, typ uslugi, param2-string z nazwa, param 3-funkcja zwracajaca wskaznik na skaner
   {UslugaNetBios, "netbios", OtworzNetBios},
   {UslugaKoniec, "", NULL}
   };

class SkanerFTP : public ISkaner{
    protected:
    bool polaczony;
    string komputer;
    string aktualny_katalog;
    netbuf * polaczenie, * data;
    ostream & plik;
    public:

	/*
	 * Inicjalizujemy biblioteke ftplib
	 */
	static void InicjalizujSkanerFTP(){
    	    FtpInit();
	}

	/*
	 * Zamykamy skaner FTP
	 * prawdopodobnie tej funkcji  nie bedzie
	 */
	static void ZamknijSkanerFTP(){
	}//USUNAC - cameleeck

	/*
	 * Konstruktor
	 */
	SkanerFTP(ostream & plik_log): plik(plik_log){
            polaczony = false;
	    data = polaczenie = NULL;
	}

	/*
	 * Destruktor
	 */
	~SkanerFTP(){
            Rozlacz();
	}

	/*
	 * Laczy sie i loguje do serwera FTP
	 * @param komputer	Nazwa zdalnego komputera
	 *
	 * @return	True jesli polaczenie i logowanie sie udalym w przeciwnym wypadku False
	 */
	bool Polacz(const string & komputer){
	    char buf[256];
	    plik<<"Polacz() [ftp]\n";
	    if (polaczony)
	    {
        	plik<<"Bylem polaczony, wolam Rozlacz() przed ponownym laczeniem."<<endl;
		Rozlacz();
	    }
	    this->komputer = komputer;
	    aktualny_katalog = "/";
	    if(!(polaczony = FtpConnect(komputer.c_str(), &polaczenie))){
		plik<<"Nie udalo sie polaczyc\n";
		return false;
	    }

	    if(!(polaczony = FtpLogin("anonymous", "TO.SA.TESTY.QUICKSEARCH.SKANERA-meloman@radiopolska.pl", polaczenie))){
		plik<<"Blad podczas logowania\n";
		FtpQuit(polaczenie);
		return false;
	    }
	    FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, polaczenie);
	    FtpSysType(buf, 256, polaczenie);
	    plik<<"Polaczony poprawnie! :)"<<endl;
	    return polaczony;
	}

	/*
	 * Rozlacza sie z serwerm FTP
	 */
	void Rozlacz(){
	    if(polaczony){
		plik<<"Rozlacz() [ftp]\n";
		if(data)
		    FtpClose(data);
		FtpQuit(polaczenie);
	    }
	    data = NULL;
	    polaczenie = NULL;
	    polaczony = false;
         }

	/*
	 * Laczy pownownie
	 * @return True jezeli sie udalo
	 */
	bool PolaczPonownie(){
            Rozlacz();
            return Polacz(komputer);
	}
//ROZKMINIC TA FUNKCJE - cameleeck
	Pliki PobierzPliki(ostream & plik_log){
	    Pliki wynik;
	    char  buf[1000];
	    char name[257];
	    long long int size;
	    //unsigned long long int wrong_size = 100*1024*1024*1024;
	    netbuf * data;

	    if(!FtpAccess("", FTPLIB_DIR_VERBOSE, FTPLIB_ASCII, polaczenie, &data)){
		ZalogujBlad(plik, (char*)((string)"FTPACCESS: " + aktualny_katalog).c_str());
		return wynik;
	    }
	    while(FtpRead((void *)buf, 1000, data)){
		if(buf[0] != 'd' && buf[0] != '-')
		    continue;
		sscanf(buf, "%*s%*d%*s%*s%lld%*s%*d%*s%*c%[^\n]", &size,name);
		if(!strcmp(".", name))
		    continue;
		if(!strcmp("..", name))
		    continue;
		Plik plik;
		plik.katalog =( buf[0] == 'd');
		if(size < 0){
			//size = (long long int)UINT_MAX - size;
			size = 0;   // druga wersja ==> jebie nas to ze ktos nam zwraca ujemny rozmiar
		}
		plik.rozmiar = (unsigned long long int)size;
		plik.nazwa.assign(name);
		wynik.push_back(plik);
	    }
	    FtpClose(data);
	    return wynik;
	}

	/*
	 * ROZKMINIC - cameleeck
	 */
	bool WejdzDoKatalogu(const string & katalog, ostream & plik_log){
	    bool udane;
	    string kat;
	    aktualny_katalog += katalog;
	    aktualny_katalog += "/";
	    kat = aktualny_katalog;
	    udane = FtpChdir(aktualny_katalog.c_str(), polaczenie);
	    if(!udane){
		int pozycja = aktualny_katalog.size()-2;
        	while (pozycja >= 0 && aktualny_katalog[pozycja] != '/')
            	    pozycja--;
        	aktualny_katalog = aktualny_katalog.substr(0, pozycja+1);
		ZalogujBlad(plik,(char*)((string)"Blad podczas wchodzenia do: " + kat).c_str());
	    }
            return udane;
        }

	bool WyjdzZKatalogu(ostream & plik_log){
	    string stary_katalog = aktualny_katalog;
	    int udane;
	    int pozycja = aktualny_katalog.size()-2;
	    while (pozycja >= 0 && aktualny_katalog[pozycja] != '/')
		pozycja--;
	    aktualny_katalog = aktualny_katalog.substr(0, pozycja+1);
	    udane = FtpChdir(aktualny_katalog.c_str(), polaczenie);
	    if(!udane)
	    	ZalogujBlad(plik,(char*)((string)"Blad podczas wychodzenia z: " + stary_katalog).c_str());
            return udane;
	}

   };
//DZIWNA FUNKCJA - cameleeck
ISkaner * OtworzNetBios(const string & komputer, ostream & plik){
    return NULL;
}
ISkaner * OtworzFTP(const string & komputer, ostream & plik)
{
    SkanerFTP * skaner = new SkanerFTP(plik);
    if (!skaner->Polacz(komputer)){
	delete skaner;
        skaner = 0;
    }
    return skaner;
}

ZarzadcaSkanowania & ZarzadcaSkanowania::PobierzZarzadceSkanowania()
{
    AutoZamek zamek(sekcja_zarzadcy);
    if (zarzadca_skanowania == 0)
	zarzadca_skanowania = new ZarzadcaSkanowania();
    return *zarzadca_skanowania;
}

ZarzadcaSkanowania::ZarzadcaSkanowania()
{
    aktualny_stan = Zatrzymany;
    maksymalna_ilosc_watkow = 5; // MODYFIKOWANE z 5 - cameleeck
    pthread_attr_init(&thread_attr);
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&watek_zarzadcy, NULL, WatekZarzadcy, (void *) this);
    pthread_join(watek_zarzadcy, (void**) NULL);
}

ZarzadcaSkanowania::~ZarzadcaSkanowania()
{
    pthread_attr_destroy(&thread_attr);
    Przerwij();
}

void * ZarzadcaSkanowania::WatekZarzadcy(void * parametr)
{
    zarzadca_skanowania = reinterpret_cast<ZarzadcaSkanowania *>(parametr);
    zarzadca_skanowania->FunkcjaZarzadzajaca();
    return 0;
}

void ZarzadcaSkanowania::WatekSkanujacyZakonczony(WatekSkanujacy * watek)
{
    AutoZamek zamek(sekcja_zmiennych);
    WatkiSkanujace::iterator it = watki_skanujace.find(watek);
    if(it != watki_skanujace.end())
	it->second.zakonczono = true;
}

void ZarzadcaSkanowania::WatekSkanujacyPolaczony(WatekSkanujacy * watek)
{
    AutoZamek zamek(sekcja_zmiennych);
//    cout<<"KTORYS watek sie polaczyl: "<<watek->DajNazwe()<<endl;;
    WatkiSkanujace::iterator it = watki_skanujace.find(watek);
    if(it != watki_skanujace.end())
	it->second.polaczony = true;
}

ZarzadcaSkanowania::StanSkanera ZarzadcaSkanowania::JakiStan(){
    AutoZamek zamek(sekcja_zmiennych);
    return aktualny_stan;
}

void ZarzadcaSkanowania::Przerwij(){
    AutoZamek zamek(sekcja_zmiennych);
    if (aktualny_stan != Nieaktywny)
        aktualny_stan = PrzerywaneSkanowanie;
}

void WyslijPlikiNaSerwer(){
    system("./kopiuj");
}






/*   Opcje & opcje = Opcje::PobierzOpcje();

   HINTERNET internet = InternetOpen("Qbeuek scanner", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
   HINTERNET sesja = InternetConnect(internet, opcje.PobierzSerwer().c_str(), INTERNET_DEFAULT_FTP_PORT, opcje.PobierzLogin().c_str(), opcje.PobierzHaslo().c_str(), INTERNET_SERVICE_FTP, 0, 0);

   bool wyslano = false;
   WIN32_FIND_DATA dane_find;
   unsigned indeks = 0;
   while (dane_uslug[indeks].usluga != UslugaKoniec)
      {
      HANDLE szukanie = FindFirstFile((opcje.PobierzKatalogSkanera() + "*." + dane_uslug[indeks].nazwa).c_str(), &dane_find);
      if (szukanie != INVALID_HANDLE_VALUE)
         {
         do
            {
            if (FtpPutFile(sesja, (opcje.PobierzKatalogSkanera() + dane_find.cFileName).c_str(), (opcje.PobierzZdalnyKatalog() + dane_find.cFileName).c_str(), FTP_TRANSFER_TYPE_BINARY, NULL))
               {
               DeleteFile((opcje.PobierzKatalogSkanera() + dane_find.cFileName).c_str());
               wyslano = true;
               }
            } while (FindNextFile(szukanie, &dane_find));
         FindClose(szukanie);
         }
      indeks++;
      }

   if (wyslano)
      FtpPutFile(sesja, "przebuduj", "przebuduj", FTP_TRANSFER_TYPE_BINARY, NULL);

   InternetCloseHandle(sesja);
   InternetCloseHandle(internet);
  */
//}

void SkasujPlikiCzesciowe(){
/*   Opcje & opcje = Opcje::PobierzOpcje();

   WIN32_FIND_DATA dane_find;
   HANDLE szukanie = FindFirstFile((opcje.PobierzKatalogSkanera() + "*.*").c_str(), &dane_find);
   if (szukanie != INVALID_HANDLE_VALUE)
      {
      do
         {
         DeleteFile((opcje.PobierzKatalogSkanera() + dane_find.cFileName).c_str());
         } while (FindNextFile(szukanie, &dane_find));
      FindClose(szukanie);
      }
  */
}

void ZarzadcaSkanowania::FunkcjaZarzadzajaca(){
	cout <<"przed mutexem\n";
    sekcja_zarzadcy.Wyjdz();
    cout<<"QuickSearch\n";
//start sakanera FTP i kasowanie poprzedniej bazy
    cout<<"Skaner FTP...\n";
    SkanerFTP::InicjalizujSkanerFTP();
//    cout<<"OK\nSkaner NetBios...";
    //SkanerNetBios::InicjalizujSkanerNetBios(); - zastanawiam sie czemu jest zakomentowana ? - cameleeck
	cout<<"OK\n";
    SkasujPlikiCzesciowe(); // Wykomentowana FUNKCJA wyglada na zbedna moze warto napisac - cameleeck
    cout<<"OK skasuj pliki\n";
    int x=0;
    bool jeszcze_raz;
    struct timespec ts;
    ts.tv_nsec = 0;//200*1000000;
    ts.tv_sec = 15; //0;
    while (true){
        sekcja_zmiennych.Wejdz();
//	cout <<"w sekcji\n";
        WatkiSkanujace::iterator it;

/*	if(!(x% 1000)){
	    for(it = watki_skanujace.begin(); it != watki_skanujace.end(); it++)
		cout<<it->second.zakonczono<<" "<<it->first->DajNazwe()<<endl;
	    cout<<endl;
	}
	x++;
*/        do{
		//cout <<"petla do zabijania watkow\n";
    	    jeszcze_raz = false;
            for (it = watki_skanujace.begin(); it != watki_skanujace.end(); it++)
	    {
    		if (it->second.zakonczono) // second - typu dane watku ? - cameleeck
		{
            	    delete it->first;
            	    watki_skanujace.erase(it);
            	    jeszcze_raz = true;
            	    break;
    		}
		else if(it->second.usluga == UslugaNetBios)
		{
		    if(waitpid((int)it->second.uchwyt, NULL, WNOHANG))
		    {
                	delete it->first;
	        	watki_skanujace.erase(it);
    	        	jeszcze_raz = true;
	    		break;
		    }
		}
		if(it->second.usluga == UslugaFTP && it->second.polaczony == false && time(NULL) - it->second.start >= TIMEOUT_POLACZENIA
		    || time(NULL) - it->second.start >= TIMEOUT_SKANOWANIA)
		{
		    if(it->second.usluga == UslugaFTP)
		    {
		        cout<<"kasujemy watek: "<<it->first->DajNazwe()<<endl;
			pthread_cancel(it->second.uchwyt);
		    }
		    else
		    {
			cout<<"zabijamy proces "<<it->first->DajNazwe()<<endl;
			kill((pid_t)it->second.uchwyt, SIGKILL);
		    }
		    delete it->first;
	    	    watki_skanujace.erase(it);
    	    	    jeszcze_raz = true;
	    	    break;
		}
	    }
	}while (jeszcze_raz);
	cout<<"Koniec petli zabijajacej watki!\n";
	switch (aktualny_stan){
    	    case PrzerywaneSkanowanie:{
		cout<<"przerywane\n";
        	bool przespij_sie = false;
        	if (watki_skanujace.empty())
            	    aktualny_stan = Nieaktywny;
        	else{
            	    WatkiSkanujace::iterator it;
            	    for (it = watki_skanujace.begin(); it != watki_skanujace.end(); it++)
                	it->first->Przerwij();
            	    przespij_sie = true;
                }
        	sekcja_zmiennych.Wyjdz();
        	if (przespij_sie)
		    nanosleep(&ts, NULL);
        	break;
    	    }
    	    case Nieaktywny:{
		cout<<"nieaktywny\n";
        	sekcja_zmiennych.Wyjdz();
        	SkanerFTP::ZamknijSkanerFTP();
        	return;
    	    }
            case Zatrzymany:{
	    	cout<<"zatrzymany\n";
        	time_t aktualny_czas = time(NULL);
        	if (aktualny_czas > Opcje::PobierzOpcje().OdczytajCzasSkanowania()){
            	    numer_skanowanego = 0;
            	    numer_uslugi = 0;
            	    aktualny_stan = AktywneSkanowanie;
            	    WczytajListeHostow("http://ustrodb.ustronie.pw.edu.pl/hosts.php");
            	    sekcja_zmiennych.Wyjdz();
                }
        	else
		{
            	    cout<<"nie czytam hostow - zbyt malo czasu minelo od poprzedniego skanowania\n";
		    sekcja_zmiennych.Wyjdz();
		    nanosleep(&ts, NULL);
                }
        	break;
    	    }
            case AktywneSkanowanie:{
		    cout<<"aktywne\n";
	    /*
		jezeli mozna uruchamiac watki to stworz nowy watek, uruchom go, ftp dla danego komap
		w kolenym obiegu dla samby, a pozniej od nowa dla kolejnego kompa

	    */
        	if ((watki_skanujace.size() < maksymalna_ilosc_watkow) && (numer_skanowanego < komputery.size()))
		{
	    	//    printf("wiecej watkow(%d): %d / %d\n", watki_skanujace.size(), numer_skanowanego, komputery.size());
            	    WatekSkanujacy * nowy_watek = new WatekSkanujacy(komputery[numer_skanowanego], ips[numer_skanowanego], dane_uslug[numer_uslugi].usluga);
            	    DaneWatku dane_watku;
            	    dane_watku.zakonczono = false;
		    dane_watku.polaczony = false;
		    dane_watku.start = time(NULL);
		    dane_watku.usluga = dane_uslug[numer_uslugi].usluga;
            	    if((dane_watku.uchwyt = nowy_watek->UruchomWatek()))
            		watki_skanujace.insert(make_pair(nowy_watek, dane_watku));
		    else
			delete nowy_watek;
            	    numer_uslugi++;
            	    if (dane_uslug[numer_uslugi].usluga == UslugaKoniec)
		    {
                	cout<<"usluga koniec\n";
			numer_uslugi = 0;
                	numer_skanowanego++;
                    }
            	    sekcja_zmiennych.Wyjdz();
                }
	       /*
	        jezeli skanowanie sie skonczylo wyjsdz SK i wyslij na serwer
	       */
        	else if ((numer_skanowanego == komputery.size()) && watki_skanujace.empty())
		{
	    	    cout<<"wszyscy przeskanowani\n";
            	    time_t aktualny_czas = time(NULL);
            	    Opcje::PobierzOpcje().ZapiszCzasSkanowania(aktualny_czas + 4 * 60 * 60);
            	    aktualny_stan = Zatrzymany;
            	    sekcja_zmiennych.Wyjdz();
            	    WyslijPlikiNaSerwer();
//	       return;
                }
	       /*
	       jezeli trwa skanowanie(czyli nie wszystkie watki sie zakonczyly) wyjdz z SK i idz spac na 100 sec
	       */
        	else{
		    cout<<"pelna list watkow: "<<watki_skanujace.size()<<endl;
		    sekcja_zmiennych.Wyjdz();
		    nanosleep(&ts, NULL);
                }
        	break;
    	    }
	}
    }
}

void ZarzadcaSkanowania::WczytajListeHostow(const string & nazwa_pliku){
    komputery.clear();
    ips.clear();
    ifstream plik;
    system("wget -q --no-check-certificate --output-document=hoststemp http://ustrodb/hosts.php");
    plik.open("hosts");
    string linia;
    while (true){
        getline(plik, linia);
        if (linia.size() == 0)
            break;
	cout <<linia;
        unsigned start = linia.find_first_of('\t');
	ips.push_back(linia.substr(0, start));
        unsigned koniec = linia.find_first_of('\t', start +1);
        komputery.push_back(linia.substr(start+1, koniec - start - 1));
    }
    plik.close();
    cout<<"Lista wczytana\n";
}

WatekSkanujacy::WatekSkanujacy(const string & nazwa_komputera, const string & ip, Usluga usluga) : nazwa_komputera(nazwa_komputera), ip(ip), usluga(usluga){
    czy_przerwac = false;
    skaner = 0;
    baza = 0;
}

void * WatekSkanujacy::Watek(void * parametr){
    WatekSkanujacy * watek_skanujacy = reinterpret_cast<WatekSkanujacy *>(parametr);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    watek_skanujacy->RozpocznijSkanowanie();
    free(watek_skanujacy);
    return 0;
}

unsigned long int WatekSkanujacy::UruchomWatek(){
    int x;
    if(usluga == UslugaFTP){
	cout<<"[ftp] tworze watek dla: "<<nazwa_komputera<<endl;
	if(x = pthread_create(&id_watku, &(ZarzadcaSkanowania::PobierzZarzadceSkanowania().thread_attr), Watek, (void *) this)){
	    cout<<"[ftp] nie udalo sie utworzyc watku: "<<x<<endl;;
	    id_watku = 0;
	}
	return id_watku;
    }
    int pid;
    if((pid = fork()) < 0) return 0;
    if(!pid){
        cout<<"START samba: "<<nazwa_komputera<<endl;
        execl("samba", " samba", nazwa_komputera.c_str(), ip.c_str(), Opcje::PobierzOpcje().PobierzKatalogSkanera().c_str(), NULL);
    }
    else{

	//    wait(NULL);
    }
    return (unsigned long int)pid;
}

void WatekSkanujacy::RozpocznijSkanowanie(void){
//   bool przerwano = false;
/*
    Otwiera plik na wyniki skanu, ustawia odpowiedni skaner
    otwiera baze, rozpoczyna skanowanie katalogow zkatalogiem - maxint*/
    cout<<"[ftp] Rozpoczynam skanowanie: "<<nazwa_komputera<<endl;
    ofstream plik_log;
    plik_log.open((nazwa_komputera + "." + dane_uslug[usluga].nazwa + ".log").c_str(), ios_base::trunc | ios_base::out);
    try{
	//otwiwera polaczenie  z kompem
	plik_log<<"start: "<<nazwa_komputera<<" usluga "<<dane_uslug[usluga].nazwa<<endl;
        skaner = dane_uslug[usluga].Kreator(ip, plik_log);
        if (skaner)
	{
	    plik_log<<"polaczylem sie z: "<<nazwa_komputera<<" usluga "<<dane_uslug[usluga].nazwa<<endl;
	    ZarzadcaSkanowania::PobierzZarzadceSkanowania().WatekSkanujacyPolaczony(this);
	    plik_log<<"po WatekSkanujacyPolaczony()"<<endl;
            baza = OtworzBazePlik(Opcje::PobierzOpcje().PobierzKatalogSkanera() + nazwa_komputera + "." + dane_uslug[usluga].nazwa);
	    plik_log<<"po OtworzBazePlik()"<<endl;
            SkanujKatalog(UINT_MAX, 0, plik_log);
	    plik_log<<"po SkanujKatalog()"<<endl;
        }
	plik_log<<"koniec: "<<nazwa_komputera<<" usluga "<<dane_uslug[usluga].nazwa<<endl;
    }
    catch (Wyjatek w){
	if(plik_log.is_open())
	plik_log << "Wyjatek: "<< w.opis << endl;
    }
    if(plik_log.is_open())
	plik_log.close();
    delete baza;
    delete skaner;
    baza = 0;
    skaner = 0;
    //if (przerwano)
    //   remove(((string)katalog_skanera + nazwa_komputera + "." + dane_uslug[usluga].nazwa).c_str());

    ZarzadcaSkanowania::PobierzZarzadceSkanowania().WatekSkanujacyZakonczony(this);
    void * cos;
    pthread_exit(NULL);

}

bool WatekSkanujacy::PolaczPonownie(ostream & plik_log){
   //cout<<"bool WatekSkanujacy::PolaczPonownie(ostream & plik_log)\n";
    if (skaner->PolaczPonownie()){
        for (int i = 0; i < katalogi.size(); i++)
            if (!skaner->WejdzDoKatalogu(katalogi[i], plik_log))
        	return false;
        return true;
    }
    else
      return false;
}

void WatekSkanujacy::SkanujKatalog(unsigned katalog, unsigned poziom_katalogu, ostream & plik_log){
    const int maksymalna_ilosc_prob = 1;
    if (poziom_katalogu == 32)
        return;
    {
	AutoZamek zamek(sekcja);
         if (czy_przerwac){
            plik_log << "Przerywanie watku" << endl;
            throw Wyjatek("Przerywanie watku skanujacego");
         }
    }

    int numer_proby = 0;
    bool sukces = false;
    ISkaner::Pliki pliki;
    while (!sukces && numer_proby < maksymalna_ilosc_prob){
	try{
	 //skanuje dany katalog
            pliki = skaner->PobierzPliki(plik_log);
            sukces = true;
        }
	//na wypadke kiedy nie dalo by sie skanowac
        catch (WyjatekSkanera){
    	    numer_proby++;
            while (numer_proby < maksymalna_ilosc_prob){
        	if (PolaczPonownie(plik_log))
                break;
        	numer_proby++;
            }
	}
    }
    if (!sukces)
        throw Wyjatek("Blad podczas pobierania listy plikow");

    unsigned i;
    for (i = 0; i < pliki.size(); i++)
	//prawdopodobnie jezeli w nazwie nie ma '|'
        if (pliki[i].nazwa.find('|') == pliki[i].nazwa.npos)
            if (pliki[i].katalog){
	    //jezeli wpis jest katalogiem
	    //dodajemy do bazy
        	unsigned numer_wpisu = baza->DodajWpis(katalog, pliki[i].nazwa + "/", 0);
        	sukces = false;
        	numer_proby = 0;
        	while (!sukces && numer_proby < maksymalna_ilosc_prob){
            	    try{
		  //wchodzimy do tego katalogu
                	sukces = skaner->WejdzDoKatalogu(pliki[i].nazwa, plik_log);
                    }
            	    catch (WyjatekSkanera){
		  //jakby cos sie nie udalo to probujemy sie polaczyc ponownie
			plik_log<<"cos sie nie udalo musimy wchodzic jeszcze raz\n";
                	numer_proby++;
                	while (!sukces && numer_proby < maksymalna_ilosc_prob){
                    	    if (PolaczPonownie(plik_log))
                    		break;
                    	    numer_proby++;
            		}
        	    }
            	}
        	if (sukces){
	       //wrzucamy go do listy katalogow zeby w przypadku zerwania polaczenie moc tam wrocic
            	    katalogi.push_back(pliki[i].nazwa);
	       //skanujemy katalog
            	    SkanujKatalog(numer_wpisu, poziom_katalogu+1, plik_log);
	       //zeskanowalismy wiec mozemy go wyciagnac z listy
            	    katalogi.pop_back();
            	    sukces = false;
            	    numer_proby = 0;
            	    try{
                	sukces = skaner->WyjdzZKatalogu(plik_log);
                    }
            	    catch (WyjatekSkanera){
			plik_log<<"cos nie wyszlo przy wychodzeniu\n";
                	numer_proby++;
                	while (!sukces && numer_proby < maksymalna_ilosc_prob){
                    	    if (PolaczPonownie(plik_log))
                    	    break;
                    	numer_proby++;
//		     printf("Blad wyjscia z kat\n");
                        }
                    }
            	    if (numer_proby >= maksymalna_ilosc_prob)
                    throw Wyjatek("Blad podczas opuszczania katalogu");
                }
    	    }
	    //jezeli pozycja jest plikiem dodajemy go do bazy
            else
        	baza->DodajWpis(katalog, pliki[i].nazwa, pliki[i].rozmiar);
}

void WatekSkanujacy::Przerwij(){
    AutoZamek zamek(sekcja);
    czy_przerwac = true;
}
